package com.monkeyboy.first.jmm;

import java.util.concurrent.CountDownLatch;

/**
 * 描述：     演示重排序的现象 “直到达到某个条件才停止”，测试小概率事件
 * 一共有四种情况
 * 1. a=1;x=b(0);b=1;y=a(1),最终结果是x=0,y=1  (正常运行流程，第一个线程先运行，第二个线程后运行)
 * 2. b=1;y=a(0);a=1;x=b(1),最终结果是x=1,y=0  (第二个线程先运行，第一个线程后运行)
 * 3. b=1;a=1;x=b(1);y=a(1),最终结果x=1,y=1 (第一个线程先给a赋值后第二个线程给b赋值，然后再执行第一个线程给x赋值，第二个线程给y赋值)
 *
 * 上面三种情况都能正常理解，关键的是还有第四种情况,就是发生了重排序
 * 4. x=b(0);y=a(0);a=1;b=1,最终结果x=0,y=0 (每个线程里面的赋值语句发生了重新排序)
 *      类似第一个线程中：
 *          {                                     {
 *              a=1;            ==============>    x=b;
 *              x=b;                               a=1;
 *          }                                     }
 *    此时赋值的执行流程就有下面这种情况：
 *      y=a;
 *      a=1;
 *      x=b;
 *      b=1;
 *      所以最终输出的xy就为00
 *
 */
public class OutOfOrderExecution {

    private static int x = 0, y = 0;
    private static int a = 0, b = 0;

    public static void main(String[] args) throws InterruptedException {
        int i = 0;
        for (; ; ) {
            i++;
            x = 0;
            y = 0;
            a = 0;
            b = 0;

            CountDownLatch latch = new CountDownLatch(3);

            Thread one = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        latch.countDown();
                        latch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    a = 1;
                    x = b;
                }
            });
            Thread two = new Thread(new Runnable() {
                @Override
                public void run() {
                    try {
                        latch.countDown();
                        latch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                    b = 1;
                    y = a;
                }
            });
            two.start();
            one.start();
            latch.countDown();
            one.join();
            two.join();

            String result = "第" + i + "次（" + x + "," + y + ")";
            if (x == 0 && y == 0) {//如果等于00说明进行了指令的重排序
                System.out.println(result);
                break;
            } else {
                System.out.println(result);
            }
        }
    }


}
